package com

import java.awt.image.renderable.RenderableImage;

import grails.converters.JSON

import java.text.DateFormat
import java.text.SimpleDateFormat

import com.lowagie.text.pdf.AcroFields.Item;

import groovy.sql.Sql

class ContaContabilController {

	def dataSource

	static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

	def index = {
		redirect(action: "list", params: params)
	}

	def list = {
		params.max = Math.min(params.max ? params.int('max') : 10, 100)
		[contaContabilInstanceList: ContaContabil.list(params), contaContabilInstanceTotal: ContaContabil.count()]
	}

	def create = {
		def contaContabilInstance = new ContaContabil()
		contaContabilInstance.properties = params
		return [contaContabilInstance: contaContabilInstance]
	}

	def save = {
		def contaContabilInstance = new ContaContabil(params)
		if (contaContabilInstance.save(flush: true)) {
			flash.message = "${message(code: 'default.created.message', args: [message(code: 'contaContabil.label', default: 'ContaContabil'), contaContabilInstance.id])}"
			redirect(action: "show", id: contaContabilInstance.id)
		}
		else {
			render(view: "create", model: [contaContabilInstance: contaContabilInstance])
		}
	}

	def show = {
		def contaContabilInstance = ContaContabil.get(params.id)
		if (!contaContabilInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'contaContabil.label', default: 'ContaContabil'), params.id])}"
			redirect(action: "list")
		}
		else {
			[contaContabilInstance: contaContabilInstance]
		}
	}

	def edit = {
		def contaContabilInstance = ContaContabil.get(params.id)
		if (!contaContabilInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'contaContabil.label', default: 'ContaContabil'), params.id])}"
			redirect(action: "list")
		}
		else {
			return [contaContabilInstance: contaContabilInstance]
		}
	}

	def update = {
		def contaContabilInstance = ContaContabil.get(params.id)
		if (contaContabilInstance) {
			if (params.version) {
				def version = params.version.toLong()
				if (contaContabilInstance.version > version) {

					contaContabilInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [
						message(code: 'contaContabil.label', default: 'ContaContabil')]
					as Object[], "Another user has updated this ContaContabil while you were editing")
					render(view: "edit", model: [contaContabilInstance: contaContabilInstance])
					return
				}
			}
			contaContabilInstance.properties = params
			if (!contaContabilInstance.hasErrors() && contaContabilInstance.save(flush: true)) {
				flash.message = "${message(code: 'default.updated.message', args: [message(code: 'contaContabil.label', default: 'ContaContabil'), contaContabilInstance.id])}"
				redirect(action: "show", id: contaContabilInstance.id)
			}
			else {
				render(view: "edit", model: [contaContabilInstance: contaContabilInstance])
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'contaContabil.label', default: 'ContaContabil'), params.id])}"
			redirect(action: "list")
		}
	}

	def delete = {
		def contaContabilInstance = ContaContabil.get(params.id)
		if (contaContabilInstance) {
			try {
				contaContabilInstance.delete(flush: true)
				flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'contaContabil.label', default: 'ContaContabil'), params.id])}"
				redirect(action: "list")
			}
			catch (org.springframework.dao.DataIntegrityViolationException e) {
				flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'contaContabil.label', default: 'ContaContabil'), params.id])}"
				redirect(action: "show", id: params.id)
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'contaContabil.label', default: 'ContaContabil'), params.id])}"
			redirect(action: "list")
		}
	}

	/**
	 * Descrição: Metodo para escolher datas em que se ira escolher a DRE.
	 * @author: João Paulo 
	 */
	def gerarDre = {
		def contaContabilInstance = new ContaContabil()
		contaContabilInstance.properties = params

		return [contaContabilInstance: contaContabilInstance]
	}

	/**
	 * Descrição: Monta a Dre no periodo correto
	 * @author João Paulo e Alex Lima 
	 * @params Data Inicial e data Final 
	 * @return Dre
	 */
	def dre = {
		println("PARAMS-> " + params)

		List<ContaContabil> contaContabeis = ContaContabil.findAllByPaiIsNotNull()

		println("CONTAS " + contaContabeis)

		List dreContas =  new ArrayList()

		Date dataInicial = params.dataInicial
		Date dataFinal = params.dataFinal

		def sql = new Sql(dataSource)

		Map saldoContas = [
					ativo: 0,
					passivo: 0,
					receita: 0,
					custoDespesa: 0
				]

		contaContabeis.each{

			double saldo = 0

			def subTotal01 = "select sum(venda.valor) as subTotal01 from venda left join tipo_de_operacao on"
			subTotal01+="(tipo_de_operacao.id=venda.tipo_operacao_id) left join conta_contabil on"
			subTotal01+="(tipo_de_operacao.conta_debito_id=conta_contabil.id) where conta_contabil.id= :contaId and venda.date_venda between "
			subTotal01+="if(conta_contabil.resultado=TRUE, :dataInicial ,'1980-01-01') and :dataFinal"

			def paramSubtotal = [contaId: it.id, dataInicial: dataInicial, dataFinal: dataFinal ]
			def subTotal1 = sql.rows(subTotal01, paramSubtotal)

			//converte e verifica se é null
			double saldo1
			if (subTotal1.subTotal01[0] == null){
				saldo1 = 0.0
			}else{
				saldo1 = Double.parseDouble(subTotal1.subTotal01[0].toString())
			}

			def subTotal02 = " select sum(venda.valor)  as subTotal02 from venda left join tipo_de_operacao on"
			subTotal02 +=" (tipo_de_operacao.id=venda.tipo_operacao_id) left join conta_contabil on"
			subTotal02 +=" (tipo_de_operacao.conta_credito_id=conta_contabil.id) where conta_contabil.id= :contaId and"
			subTotal02 +=" venda.date_venda between if(conta_contabil.resultado=TRUE, :dataInicial,'1980-01-01') and :dataFinal"

			def subTotal2 = sql.rows(subTotal02, paramSubtotal)

			println(subTotal2)
			//converte e verifica se é null
			double saldo2
			if (subTotal2.subTotal02[0] == null){
				saldo2 = 0.0
			}else{
				saldo2 = Double.parseDouble(subTotal2.subTotal02[0].toString())
			}

			def subTotal03 = "select sum(gastos.valor) as subTotal03 from gastos left join tipo_de_operacao on"
			subTotal03 += "(tipo_de_operacao.id=gastos.tipo_operacao_id) left join conta_contabil on"
			subTotal03 += " (tipo_de_operacao.conta_debito_id=conta_contabil.id) where conta_contabil.id= :contaId"
			subTotal03 += " and gastos.date_gasto between if(conta_contabil.resultado=TRUE, :dataInicial,'1980-01-01') and :dataFinal"

			def subTotal3 = sql.rows(subTotal03, paramSubtotal)

			//converte e verifica se é null
			double saldo3
			if (subTotal3.subTotal03[0] == null){
				saldo3 = 0.0
			}else{
				saldo3 = Double.parseDouble(subTotal3.subTotal03[0].toString())
			}

			def subTotal04 = "select sum(gastos.valor) as subTotal04 from gastos left join tipo_de_operacao on"
			subTotal04 += "(tipo_de_operacao.id=gastos.tipo_operacao_id) left join conta_contabil on"
			subTotal04 += " (tipo_de_operacao.conta_credito_id=conta_contabil.id) where conta_contabil.id= :contaId "
			subTotal04 += "and gastos.date_gasto between if(conta_contabil.resultado=TRUE, :dataInicial,'1980-01-01') and :dataFinal"

			def subTotal4 = sql.rows(subTotal04, paramSubtotal)


			//converte e verifica se é null
			double saldo4
			if (subTotal4.subTotal04[0] == null){
				saldo4 = 0.0
			}else{
				saldo4 = Double.parseDouble(subTotal4.subTotal04[0].toString())
			}

			saldo = saldo1 - saldo2 + saldo3 - saldo4

			dreContas.add(contaContabel: it,
					saldoConta: saldo)

			if (it.pai.codigo == ContaContabil.ATIVO){
				saldoContas.ativo = saldoContas.ativo + saldo
			}else
			if (it.pai.codigo == ContaContabil.PASSIVO){
				saldoContas.passivo = saldoContas.passivo + saldo
			}else
			if (it.pai.codigo == ContaContabil.RECEITA){
				saldoContas.receita = saldoContas.receita + saldo
			}
			else
			if (it.pai.codigo == ContaContabil.CUSTOS_DESPESAS){
				saldoContas.custoDespesa = saldoContas.custoDespesa + saldo
			}


			//println("CONTA CONTABIl- "+ it)

			//println (saldo1)
			//println (saldo2)
			//println (saldo3)
			//println (saldo4)

		}
		println("SALDO-> "+saldoContas)

		return [dreContas: dreContas, saldoContas: saldoContas]

	}
	/*subtotal1
	 select sum(venda.valor) as subtotal1 from venda left join tipo_de_operacao on 
	 (tipo_de_operacao.id=venda.tipo_operacao_id) left join conta_contabil on 
	 (tipo_de_operacao.conta_debito_id=conta_contabil.id) where conta_contabil.id=7 and venda.date_venda between 
	 if(conta_contabil.resultado=TRUE, '2011-11-01','1980-01-01') and '2011-11-30';
	 /*subtotal2
	 select sum(venda.valor)  as subtotal2 from venda left join tipo_de_operacao on 
	 (tipo_de_operacao.id=venda.tipo_operacao_id) left join conta_contabil on 
	 (tipo_de_operacao.conta_credito_id=conta_contabil.id) where conta_contabil.id=7 and venda.date_venda between 
	 if(conta_contabil.resultado=TRUE, '2011-11-01','1980-01-01') and '2011-11-30';
	 /*subtotal3
	 select sum(gastos.valor) as subtotal3 from gastos left join tipo_de_operacao on (tipo_de_operacao.id=gastos.tipo_operacao_id) left join conta_contabil on (tipo_de_operacao.conta_debito_id=conta_contabil.id) where conta_contabil.id=7 and gastos.date_gasto between if(conta_contabil.resultado=TRUE, '2011-11-01','1980-01-01') and '2011-11-30';
	 /*subtotal4
	 select sum(gastos.valor) as subtotal4 from gastos left join tipo_de_operacao on (tipo_de_operacao.id=gastos.tipo_operacao_id) left join conta_contabil on (tipo_de_operacao.conta_credito_id=conta_contabil.id) where conta_contabil.id=7 and gastos.date_gasto between if(conta_contabil.resultado=TRUE, '2011-11-01','1980-01-01') and '2011-11-30';
	 */

}
